﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.Linq;

using Happy.Activities.Domain.Workflows;
using Happy.Activities.Domain.WorkflowInstances;

namespace Happy.Activities.Domain.Test
{
    [TestClass]
    public class ConditionWorkflowTest
    {
        [TestMethod]
        public void Condition_Test()
        {
            var workflow = new Workflow
            {
                Id = Guid.NewGuid()
            };

            workflow.AddActivity(new ManualActivity
            {
                Id = Guid.NewGuid(),
                DisplayName = "A",
                IsFinal = false,
                Name = "A"
            }, true);
            workflow.AddActivity(new ManualActivity
            {
                Id = Guid.NewGuid(),
                DisplayName = "B1",
                IsFinal = true,
                Name = "B1"
            });
            workflow.AddActivity(new ManualActivity
            {
                Id = Guid.NewGuid(),
                DisplayName = "B2",
                IsFinal = true,
                Name = "B2"
            });

            var routerA_B1 = new Router
            {
                Id = Guid.NewGuid(),
                DisplayName = "A->B1",
                FromId = workflow["A"].Id,
                ToId = workflow["B1"].Id
            };
            routerA_B1.SetCondition(new ScriptRouterCondition("性别==\"男\""));
            workflow.AddRouter(routerA_B1);

            var routerA_B2 = new Router
            {
                Id = Guid.NewGuid(),
                DisplayName = "A->B2",
                FromId = workflow["A"].Id,
                ToId = workflow["B2"].Id
            };
            routerA_B2.SetCondition(new ScriptRouterCondition("性别==\"女\""));
            workflow.AddRouter(routerA_B2);


            var instance = new WorkflowInstance(workflow);
            var args = new Dictionary<string, object>
            {
                { "性别", "女" }
            };


            instance.Run(args);
            var activityInstances = instance.GetActivityInstances();
            var routerInstances = instance.GetRouterInstances();

            Assert.AreEqual(1, activityInstances.Length);
            Assert.AreEqual(ActivityState.Entered, activityInstances[0].State);
            Assert.AreEqual(WorkflowState.Running, instance.State);
            Assert.AreEqual(0, routerInstances.Length);


            instance.Resume(activityInstances[0].Id, args);
            activityInstances = instance.GetActivityInstances();
            routerInstances = instance.GetRouterInstances();

            Assert.AreEqual(2, activityInstances.Length);
            Assert.AreEqual(ActivityState.Exited, activityInstances[0].State);
            Assert.AreEqual(ActivityState.Entered, activityInstances[1].State);
            Assert.AreEqual(WorkflowState.Running, instance.State);
            Assert.AreEqual(1, routerInstances.Length);


            instance.Resume(activityInstances[1].Id, args);
            activityInstances = instance.GetActivityInstances();
            routerInstances = instance.GetRouterInstances();

            Assert.AreEqual(2, activityInstances.Length);
            Assert.AreEqual(ActivityState.Exited, activityInstances[0].State);
            Assert.AreEqual(ActivityState.Exited, activityInstances[1].State);
            Assert.AreEqual(WorkflowState.Completed, instance.State);
            Assert.AreEqual(1, routerInstances.Length);
            Assert.AreEqual("B2", workflow[activityInstances[1].ActivityId].Name);
        }
    }
}
